#include "bootpack.h"

struct FIFO32 *mousefifo;
int mousedata;

void inthandler2c(int *esp)
/* 鼠标中断 */
{
	int data;
	io_out8(PIC1_OCW2, 0x64);
	io_out8(PIC0_OCW2, 0x62);
	data = io_in8(PORT_KEYDAT);
	fifo32_set(mousefifo, data + mousedata);
	return;
}

#define KEYCMD_SENDTO_MOUSE     0xd4
#define MOUSECMD_ENABLE         0xf4

void enable_mouse(struct FIFO32 *fifo, int data, struct MOUSE_DEC *mdec)
{
    mousefifo = fifo;
    mousedata = data;
    wait_KBC_sendready();
    io_out8(PORT_KEYCMD, KEYCMD_SENDTO_MOUSE);
    wait_KBC_sendready();
    io_out8(PORT_KEYDAT, MOUSECMD_ENABLE);
    /* if done, KBC will return 0xfa */
    mdec->phase = 0;    /* wait 0xfa */
    return;     
}

int mouse_decode(struct MOUSE_DEC *mdec, unsigned char dat)
{
    if (mdec->phase == 0)   /* wait 0xfa */
    {
        if (dat == 0xfa)
        {
            mdec->phase = 1;
        }
        return 0;
    }
    if (mdec->phase == 1)   /* wait first byte */
    {
        if ((dat & 0xc8) == 0x08)  /* 如果数据正确 */
        {
            mdec->buf[0] = dat;
            mdec->phase = 2;
        }
        return 0;
    }
    if (mdec->phase == 2) /* wait second byte */
    {
        mdec->buf[1] = dat;
        mdec->phase = 3;
        return 0;
    }
    if (mdec->phase == 3)   /* wait third byte */
    {
        mdec->buf[2] = dat;
        mdec->phase = 1;
        mdec->btn = mdec->buf[0] & 0x07;
        mdec->x = mdec->buf[1];

        mdec->y = mdec->buf[2];
        if ((mdec->buf[0] & 0x10) != 0)
        {
            mdec->x |= 0xffffff00;
        }
        if ((mdec->buf[0] & 0x20) != 0)
        {
            mdec->y |= 0xffffff00;
        }
        mdec->y = - mdec->y;    /* 鼠标y方向与画面相反 */
        return 1;
    }
    return -1;
}
